package cn.flt.lucia.Intermediate;


import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.StringUtils;
import org.hyperledger.fabric.protos.peer.Query;
import org.hyperledger.fabric.sdk.Peer;
import org.hyperledger.fabric.sdk.User;
import org.hyperledger.fabric.sdk.exception.ChaincodeEndorsementPolicyParseException;
import org.hyperledger.fabric.sdk.exception.InvalidArgumentException;
import org.hyperledger.fabric.sdk.exception.ProposalException;

import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Set;

/**
 * @author 州长在手 2020/7/6 下午2:35
 */
public class FabricManager {
    private IntermediateOrg org;

    FabricManager(IntermediateOrg org) {
        this.org = org;
    }

    public void setUser(String leagueName, String orgName, String peerName, String username, String skPath, String certificatePath) throws InvalidArgumentException {
        if (StringUtils.equals(username, org.getUsername())) {
            return;
        }
        User user = org.getUser(username);
        if (null == user) {
            IntermediateUser intermediateUser = new IntermediateUser(leagueName, orgName, peerName, username, skPath, certificatePath);
            org.setUsername(username);
            org.addUser(leagueName, orgName, peerName, intermediateUser, org.getFabricStore());
        }
        org.getClient().setUserContext(org.getUser(username));
    }

    //从channel获得peer节点信息
    public Collection<Peer> queryPeer() {
        return org.getChannel().get().getPeers();
    }

//    public Set<String> queryChannels(Peer peer) throws InvalidArgumentException, ProposalException {
//        return org.getChannel().get().queryChannels(peer);
//    }

    //获取peer节点上实例化的链码信息
//    public List<Query.ChaincodeInfo> queryInstalledChaincodes(Peer peer) throws InvalidArgumentException, ProposalException {
//        return org.getChannel().get().queryInstalledChaincodes(peer);
//    }

    public List<Query.ChaincodeInfo> queryInstantiatedChaincodes(Peer peer) throws InvalidArgumentException, ProposalException {
        return org.getChannel().get().queryInstantiatedChaincodes(peer);

    }


    public List<Query.ChaincodeInfo> queryInstantiated(Peer peer) throws InvalidArgumentException, ProposalException {
        return org.getChannel().queryInstantiated(peer);
    }

    /**
     * 安装智能合约
     *
     * @param chaincodeName 智能合约名
     */
    public JSONObject install(String chaincodeName) throws InvalidArgumentException, ProposalException {
        return org.getChainCode(chaincodeName).install(org);

    }


    /**
     * 实例化智能合约
     *
     * @param chaincodeName 智能合约名
     * @param args          初始化参数数组
     */
    public JSONObject instantiate(String chaincodeName, String[] args) throws InvalidArgumentException, ProposalException, IOException, ChaincodeEndorsementPolicyParseException {
        return org.getChainCode(chaincodeName).instantiate(org, args);
    }

    /**
     * 升级智能合约
     *
     * @param chaincodeName 智能合约名
     * @param args          初始化参数数组
     */
    public JSONObject upgrade(String chaincodeName, String[] args) throws InvalidArgumentException, ProposalException, IOException, ChaincodeEndorsementPolicyParseException {

        return org.getChainCode(chaincodeName).upgrade(org, args);
    }

    /**
     * 执行智能合约
     *
     * @param chaincodeName 智能合约名
     * @param fcn           方法名
     * @param args          参数数组
     */

    public JSONObject invoke(String chaincodeName, String fcn, String[] args) throws InvalidArgumentException, ProposalException, IOException {

        return org.getChainCode(chaincodeName).invoke(org, fcn, args);
    }

    /**
     * 查询智能合约
     *
     * @param chaincodeName 智能合约名
     * @param fcn           方法名
     * @param args          参数数组
     */
    public JSONObject query(String chaincodeName, String fcn, String[] args) throws InvalidArgumentException,ProposalException {
            return  org.getChainCode(chaincodeName).query(org, fcn, args);

    }

    /**
     * 在指定频道内根据transactionID查询区块
     *
     * @param txID transactionID
     */
    public JSONObject queryBlockByTransactionID(String txID) throws InvalidArgumentException,ProposalException,IOException{

           return org.getChannel().queryBlockByTransactionID(txID);

    }

    /**
     * 在指定频道内根据hash查询区块
     *
     * @param blockHash hash
     */
    public JSONObject queryBlockByHash(byte[] blockHash) throws InvalidArgumentException,ProposalException,IOException {

         return org.getChannel().queryBlockByHash(blockHash);

    }

    /**
     * 在指定频道内根据区块高度查询区块
     *
     * @param blockNumber 区块高度
     */
    public JSONObject queryBlockByNumber(long blockNumber) throws InvalidArgumentException,ProposalException,IOException {
        return org.getChannel().queryBlockByNumber(blockNumber);

    }

    /**
     * Peer加入频道
     *
     * @param peerName             当前指定的组织节点域名
     * @param peerLocation         当前指定的组织节点访问地址
     * @param peerEventHubLocation 当前指定的组织节点事件监听访问地址
     */
    public JSONObject joinPeer(String peerName, String peerLocation, String peerEventHubLocation, String serverCrtPath, String clientCertPath, String clientKeyPath) throws InvalidArgumentException ,ProposalException {
            return org.getChannel().joinPeer(new IntermediatePeer(peerName, peerLocation, peerEventHubLocation, serverCrtPath, clientCertPath, clientKeyPath));
    }

    /**
     * 查询当前频道的链信息，包括链长度、当前最新区块hash以及当前最新区块的上一区块hash
     */
    public JSONObject getBlockchainInfo() throws InvalidArgumentException, ProposalException{
            return org.getChannel().getBlockchainInfo();
    }
}
